﻿using Admin.NET.Core;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MOKA.TPM.Application.Enum;
using MOKA.TPM.Application.Service;
using MOKA.TPM.Application.Service.Dto;
using MOKA.TPM.Entity;
using MOKA.TPM.Service.Dto;
using MOKA.TPM.Utility;
using MOKA.TPM.Utility.Const;
using SqlSugar;

namespace MOKA.TPM.Service;

/// <summary>
/// TPM非采入库业务逻辑控制器
/// </summary>
[ApiDescriptionSettings(TPMConst.GroupName, Name = "TPM_PartIn", Order = 305)]
[NonUnify]
public class PartInService : TPMBaseService, IDynamicApiController, ITransient
{
    private readonly Service_PartInM _partInMService;
    private readonly Service_PartInD _partInDService;
    private readonly Service_PartsStock _partsStockService;
    private readonly Service_PartsStockChange _partsStockChangeService;
    private readonly Service_Parts _partsService;

    public PartInService(UserManager userManager, IHttpContextAccessor accessor, ISqlSugarClient db, Service_SysDictDetail dicService, Service_PartInM partInMService, Service_PartInD partInDService, Service_PartsStock partsStockService, Service_PartsStockChange partsStockChangeService, Service_Parts partsService)
                : base(userManager, dicService, accessor, db)
    {
        _partsService = partsService;
        _partInMService = partInMService;
        _partInDService = partInDService;
        _partsStockService = partsStockService;
        _partsStockChangeService = partsStockChangeService;
    }

    /// <summary>
    /// 根据扫描的物料编码获取物料信息
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "GetPartNoInfo"), HttpPost]
    [AllowAnonymous]
    public async Task<CommonResult> GetPartNoInfo(PartsInput input)
    {
        CommonResult result = new CommonResult();
        try
        {
            var partsEntity = await _partsService.GetOne(new PartsInput { PartNo = input.PartNo });
            if (partsEntity != null)
            {
                result.Data = partsEntity;
                result.Result = true;
            }
        }
        catch (Exception ex)
        {
            result.Data = null;
            result.Result = false;
            result.Error = ex.Message.ToString();
        }
        return result;
    }

    /// <summary>
    /// 获取入库类型
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "GetInTypeData"), HttpPost]
    [AllowAnonymous]
    public async Task<CommonResult> GetInTypeData()
    {
        CommonResult result = new CommonResult();
        try
        {
            var InTypes = await _dicService.GetDetailListByDictCode("PartInType", TPMDeviceGroupEnum.MROGroup);

            if (InTypes != null && InTypes.Count > 0)
            {
                result.Data = InTypes;
                result.Result = true;
            }
        }
        catch (Exception ex)
        {
            result.Result = false;
            result.Error = ex.Message.ToString();
        }
        return result;
    }

    ///// <summary>
    ///// 根据登录用户获取车间列表
    ///// </summary>
    ///// <returns></returns>
    //[ApiDescriptionSettings(Name = "GetWorkshopData"), HttpPost]
    //[AllowAnonymous]
    //public async Task<CommonResult> GetWorkshopData(JObject obj)
    //{
    //    CommonResult result = new CommonResult();
    //    try
    //    {
    //        string UserName = obj["UserName"].ToString();

    //        var Workshops = await dicService.GetDetailList("Workshop", TPMDeviceGroupEnum.MROGroup);
    //        if (Workshops != null && Workshops.Count > 0)
    //        {
    //            if (UserName != "admin")
    //                result.Data = Workshops.FindAll(p => (p.ItemName3 ?? "").ToLower().Contains(UserName.ToLower())
    //                                             );//车间字典，有权限控制
    //            else
    //                result.Data = Workshops;
    //            result.Result = true;
    //        }
    //    }
    //    catch (Exception ex)
    //    {
    //        result.Result = false;
    //        result.Error = ex.Message.ToString();
    //    }
    //    return result;
    //}

    ///// <summary>
    ///// 根据车间，获取仓位列表
    ///// </summary>
    ///// <returns></returns>
    //[ApiDescriptionSettings(Name = "GetLocationData"), HttpPost]
    //[AllowAnonymous]
    //public async Task<CommonResult> GetLocationData(JObject obj)
    //{
    //    CommonResult result = new CommonResult();
    //    if (obj["Workshop"].ToString() == "")
    //    {
    //        result.Result = false;
    //        result.Error = "请先选择车间";
    //        return result;
    //    }
    //    try
    //    {
    //        Guid Workshop = Guid.Parse(obj["Workshop"].ToString());
    //        List<SysDictDetailOutput> dtLocation = await dicService.GetDetailListByItemParent("Location", Workshop, TPMDeviceGroupEnum.MROGroup);

    //        if (dtLocation != null && dtLocation.Count > 0)
    //        {
    //            result.Data = dtLocation;
    //            result.Result = true;
    //        }
    //    }
    //    catch (Exception ex)
    //    {
    //        result.Result = false;
    //        result.Error = ex.Message.ToString();
    //    }
    //    return result;
    //}

    ///// <summary>
    ///// 根据车间，获取产线列表
    ///// </summary>
    ///// <returns></returns>
    //[ApiDescriptionSettings(Name = "GetFrom_LineData"), HttpPost]
    //[AllowAnonymous]
    //public async Task<CommonResult> GetFrom_LineData(JObject obj)
    //{
    //    CommonResult result = new CommonResult();
    //    if (obj["Workshop"].ToString() == "")
    //    {
    //        result.Result = false;
    //        result.Error = "请先选择车间";
    //        return result;
    //    }
    //    try
    //    {
    //        Guid Workshop = Guid.Parse(obj["Workshop"].ToString());

    // List<SysDictDetailOutput> dtLine = await dicService.GetDetailListByItemParent("Line",
    // Workshop, TPMDeviceGroupEnum.MROGroup);

    //        //foreach (var line in dtLine)
    //        //{
    //        //    if (line.ItemValue.Contains("*"))
    //        //    {
    //        //        dtLine = dal.GetLines();
    //        //        dtLine.RemoveAll(p => p.ItemValue.Contains("*"));
    //        //        break;
    //        //    }
    //        //}
    //        if (dtLine != null && dtLine.Count > 0)
    //        {
    //            result.Data = dtLine;
    //            result.Result = true;
    //        }
    //    }
    //    catch (Exception ex)
    //    {
    //        result.Result = false;
    //        result.Error = ex.Message.ToString();
    //    }
    //    return result;
    //}

    private async Task<string> GetInBillNo()
    {
        string sql = " SELECT NEXT VALUE FOR MesTpm.dbo.PartInBillNo  ";
        int num = await _db.AsTenant().GetConnectionScope(TPMConst.TPMConfigId).Ado.GetIntAsync(sql);
        return "M" + $"{num:D7}";
    }

    /// <summary>
    /// 提交入库
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "DoIn"), HttpPost]
    [AllowAnonymous]
    public async Task<CommonResult> DoIn(PartInDto paraObj)
    {
        CommonResult result = new CommonResult();
        try
        {
            // JToken paraObj = JToken.Parse(paramJson);//如果传递的为字符串，则转化为JToken（JObject基类）
            LogHelper.Write("提交入库:", paraObj.ToString());

            if (paraObj.InType == null || paraObj.InType.ToString() == "")
            {
                throw new Exception("请指定入库类型!");
            }
            if (paraObj.Workshop == null || paraObj.Workshop.ToString() == "")
            {
                throw new Exception("请指定入库车间!");
            }
            if (paraObj.PartNo == null || paraObj.PartNo.ToString() == "")
            {
                throw new Exception("请指定物料信息!");
            }
            if (paraObj.Location == null || paraObj.Location.ToString() == "")
            {
                throw new Exception("请指定仓位!");
            }
            if (paraObj.InNum == null || paraObj.InNum.ToString() == "" || paraObj.InNum < 0)
            {
                throw new Exception("请填写入库数量!");
            }

            var InType = (await _dicService.GetDetailByItemName("PartInType", "返还入库", TPMDeviceGroupEnum.MROGroup)).Id;
            if (paraObj.FromLine == InType && (paraObj.FromLine == null || paraObj.FromLine.ToString() == ""))
            {
                throw new Exception("返还入库时，请填写来自产线!");
            }

            //构建实体
            PartInM thisOne = new PartInM
            {
                Id = Guid.NewGuid(),
                BillNo = await GetInBillNo(),
                InType = paraObj.InType.Value,
                InStatus = (await _dicService.GetDetailByItemValue("PartInStatus", "09", TPMDeviceGroupEnum.MROGroup)).Id,//自动标记为已确认
                InTime = DateTime.Now,
                Workshop = paraObj.Workshop.Value,
                Remark = paraObj.Remark,
                CreateUser = paraObj.CreateUser,
                CreateTime = DateTime.Now,
                ConMan = paraObj.CreateUser,
                ConManName = paraObj.CreateUser,
                ConTime = DateTime.Now,
            };

            PartInD partInDEntity = new PartInD
            {
                Id = Guid.NewGuid(),
                BillNo = thisOne.BillNo,
                PartNo = paraObj.PartNo,
                InNum = paraObj.InNum.Value,
                Location = paraObj.Location.Value,
                FromLine = paraObj.FromLine,
            };

            List<PartInD> partInDEntitys = new List<PartInD>();

            if (await _partInMService.GetOne(new PartInMInput() { BillNo = thisOne.BillNo }) != null)//唯一索引
            {
                throw new Exception(String.Format("实体：{0}已存在！", thisOne.BillNo));
            }
            //启动事务
            using (var uow = _db.CreateContext())
            {
                if (await _partInMService.AddData(thisOne.Adapt<AddPartInMInput>()))
                {
                    partInDEntity.Id = Guid.NewGuid();
                    partInDEntity.BillNo = thisOne.BillNo;

                    partInDEntitys.Add(partInDEntity);

                    await _partInDService.AddBulkData(partInDEntitys);

                    //更新库存
                    decimal oldStock = 0.0m;

                    foreach (var item in partInDEntitys)
                    {
                        //var partStock = partsStockDal.GetOneByIdx_PartNo_Workshop_Location(item.PartNo, thisOne.Workshop.Value, item.Location.Value);
                        ////库存表没有数据的话
                        //oldStock = partStock.StockNum;
                        //partStock.StockNum = partStock.StockNum + item.InNum.Value;//累加库存

                        //partsStockDal.Update(partStock);

                        oldStock = 0.0m;
                        PartsStock partStock = await _partsStockService.GetOne(new PartsStockInput() { PartNo = item.PartNo, Workshop = thisOne.Workshop, Location = item.Location });
                        if (partStock != null)
                        {
                            oldStock = partStock.StockNum;
                            partStock.StockNum = partStock.StockNum + item.InNum;//累加库存

                            await _partsStockService.UpdateData(partStock.Adapt<UpdatePartsStockInput>());
                        }
                        else
                        {
                            PartsStock stock = new PartsStock();
                            stock.Id = Guid.NewGuid();
                            stock.PartNo = item.PartNo;
                            stock.Workshop = thisOne.Workshop;
                            stock.Location = item.Location;
                            stock.StockNum = item.InNum;
                            stock.CreateUser = thisOne.CreateUser;
                            //stock.CreateTime = DateTime.Now;
                            await _partsStockService.AddData(stock.Adapt<AddPartsStockInput>());
                        }

                        //插入库存历史表
                        PartsStockChange stockChangeEntity = new PartsStockChange();

                        stockChangeEntity.PartNo = item.PartNo;
                        stockChangeEntity.BillNo = thisOne.BillNo;
                        stockChangeEntity.ChgType = (await _dicService.GetDetailByItemValue("PartChgType", "01", TPMDeviceGroupEnum.MROGroup)).Id;
                        stockChangeEntity.Type = thisOne.InType;
                        stockChangeEntity.Workshop = thisOne.Workshop;
                        stockChangeEntity.Location = item.Location;
                        stockChangeEntity.StoreQtyChanging = oldStock;
                        stockChangeEntity.Num = item.InNum;
                        stockChangeEntity.StoreQtyChanged = oldStock + item.InNum;
                        stockChangeEntity.ToLine = null;
                        stockChangeEntity.Remark = item.Remark;
                        stockChangeEntity.CreateUser = thisOne.CreateUser;
                        // stockChangeEntity.CreateTime = thisOne.CreateTime;
                        stockChangeEntity.ConTime = thisOne.ConTime;
                        await _partsStockChangeService.AddData(stockChangeEntity.Adapt<AddPartsStockChangeInput>());
                    }
                }
                else
                {
                    throw new Exception("数据操作失败");
                }
                result.Data = thisOne.BillNo;//返回单号
                result.Result = true;
                //提交事务
                uow.Commit();
            }
        }
        catch (Exception ex)
        {
            result.Result = false;
            result.Error = ex.Message.ToString();
        }
        return result;
    }
}